Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize scroll performance #130

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

rhysd
Copy link

@rhysd rhysd commented Aug 21, 2016

Hi, I'm using this package in my Twitter client application. I found that scroll performance of timeline was not so good. So I added some rendering optimizations to this package.

Now scrolling performance is 10% faster in average. And it's especially effective when re-rendering happens so many times.

  1. I used passive DOM event because this.updateFrame doesn't prevent browser's event handling by preventDefault or stopPropagation. This is available in the latest browsers and old ones simply ignore this. So there is no breaking change.
  2. Use React's official shallow compare addon.
  3. Use requestAnimationFrame not to prevent scrolling animation. This has most impact to performance in this PR. For example, in my app, j scrolls down a timeline. When key-repeating j, there was so many setState call and re-rendering. As the result, app couldn't accept user's input any more until all input were processed. After using animation frame to render, rendering is performed once per animation frame, avoiding boring so many re-renderings by setState.

@caseywebdev
Copy link
Owner

Thanks for the PR.

  1. I've just added this to address please enable event handler as 'passive' #129.
  2. I don't think it's necessary to bring in a new package for what is already being done in a few lines of existing code.
  3. I've looked into re-adding rAF (it used to be used) but there has never been an obvious performance gain. Even the React folks have been unable to find a reason to use it for batching since the current state update batcher works well. If you can provide an example that shows definitively that using requestAnimationFrame for updating state is going to make the list more performant I'd love to see it.

@STRML
Copy link
Contributor

STRML commented Aug 23, 2016

Re: batching, I believe this is something that really should be handled at the application level - you can inject your own batcher - rather than in individual components.

I've seen performance gains from batching at rAF, but our application processes a lot of potentially redundant data updates so it is a bit special.

@pdf
Copy link

pdf commented Aug 30, 2016

@caseywebdev what might definitive proof for (3) look like? Is there a test case or methodology you can suggest? A rather unscientific test of holding down the PGDN key with raf enabled results in significantly less CPU time processing events, and effectively eliminates long frame renders:

screenshot_20160830_222920

Without raf on the left, with on the right. The selected period is small for display purposes, but the results are consistent over any time period.

@caseywebdev
Copy link
Owner

caseywebdev commented Aug 30, 2016

I just did some profiling on one of our most intensive react-list implementations (~10k rows x 100+ columns) and I found scrolling FPS was the same or even slower when using the requestAnimationFrame batching. This optimization feels like it might be case-specific, in which case @STRML's suggestion of customizing your batcher might be the best bet.

@STRML
Copy link
Contributor

STRML commented Aug 30, 2016

@pdf If you're looking for an RAF batching implementation, see ours.

@pdf
Copy link

pdf commented Aug 30, 2016

@STRML I'm aware of the raf batcher, needs work though, I'll take a look at the commit you've just made on that fork.

@caseywebdev I'm curious as to your methodology - I was just using the example page from this repo to test. What sort of FPS were you getting?

@STRML
Copy link
Contributor

STRML commented Aug 30, 2016

Yeah, I found a lot of issues with the base config with regards to page visibility and a tendency to stampede timers. I've found the above implementation to work quite well for us.

@jeveloper
Copy link

Hey all

Just curious , it seems like a good thing to merge?

@jeveloper
Copy link

Bump

@caseywebdev
Copy link
Owner

No need to bump... I'm not sold on RAF for this and it's also out of date.

@jeveloper
Copy link

Ahh, thanks for commenting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants